<?php
namespace app\classs;

class imgGd
{
    public $src;        // 背景图路径
    public $srcSx;      // 图像得宽
    public $srcSy;      // 图像得高
    public $canvas;     // 图像资源
    public $pictype;    // 图像后缀

    public $image;
    public $imageinfo;
    public $percent = 0.5;

    public static function img($src = '')
    {

        $imgGd = new imgGd();
        $imgGd->pictype = trim(strrchr($src,'.'),'.');
        $imgGd->src     = $src;
        $canvasArr      = $imgGd->transparent($imgGd->src);
        $imgGd->canvas  = $canvasArr[0];
        $imgGd->srcSx   = $canvasArr[2];
        $imgGd->srcSy   = $canvasArr[3];

        // 拷贝图片
        imagecopyresampled($imgGd->canvas,$canvasArr[1],0,0,0,0,$canvasArr[2],$canvasArr[3],$canvasArr[2],$canvasArr[3]);

        return $imgGd;
    }

    /**
     *   等比例压缩图片 public static 静态方法
     *   
     *      (1)$src        要缩放得图片路径   默认:空 
     *      (2)$out_with   缩放至宽度         默认:468
     *      (3)$prefix     另存图片得补充     默认:空
     *
     *   返回
     *      $src        图片得路径
     */

    public static function imgZoom($src = '', $imgW=468, $percent = 1,$prefix = ''){

        // 获取图片基本信息
        list($width, $height, $type, $attr) = getimagesize($src);
        // 获取图片后缀名
        $pictype = image_type_to_extension($type,false);
        // 拼接方法
        $imagecreatefrom = "imagecreatefrom".$pictype;
        // 打开传入的图片
        $in_pic = $imagecreatefrom($src);
        // 压缩后的图片长宽
        $new_width = $imgW;
        $new_height = $imgW/$width*$height;
        // 创建画布
        $canvas = imagecreatetruecolor($new_width,$new_height);
        // 拷贝图片
        imagecopyresampled($canvas,$in_pic,0,0,0,0,$new_width,$new_height,$width,$height);
        
        // 销毁输入图片
        if($prefix){
            $pictype = strrchr($src,'.');
            $src = substr($src,0,strrpos($src,'.')).'L.'.$pictype;
            imagepng($canvas,$src);//另保存到本地
        }else{
            imagepng($canvas,$src);//保存到本地
        }

        $imgGd = new imgGd();
        $imgGd->yszoom($src, $percent);
        $imgGd->compressImg($src);
        return trim($src,'.');
    }

    /**
     *   合并图片 public 共有方法
     *   $src type str
     *      $src  需要合并得图片
     *      $x    位置像素 x 轴
     *      $y    位置像素 y 轴
     *      $Zoom 缩放得像素
     *
     *   $src type arr
     *       [
     *           [
     *               0 => 需要合并得图片,
     *               1 => 位置像素 x 轴,
     *               2 => 位置像素 y 轴,
     *               3 => 缩放得像素,
     *           ]
     *       ]
     * 
     *
     *   返回
     *      $this       处理对象
     *   使用
     *      save        保存图片
     */

    public function imgPic($src = '', $x = 0, $y = 0, $Zoom = 0)
    {
        if(is_array($src)){
            foreach ($src as $k => $v) {
                if(isset($v[3]) && $v[3] > 0){

                    $src0 = imagecreatefrompng($v[0]); //二维码
                    $src0X = imagesx($src0);
                    $src0Y = imagesy($src0);

                    $new_width = $v[3];
                    $new_height = $v[3] / $src0X * $src0Y;

                    // 创建画布
                    $canvas = imagecreatetruecolor($new_width,$new_height);

                    // 拷贝图片
                    imagecopyresampled($canvas,$src0,0,0,0,0,$new_width,$new_height,$src0X,$src0Y);

                    // 剧中
                    if(!$x){
                        $x = ($this->srcSx - $new_width) / 2; //文字居中
                    }

                    imagecopymerge($this->canvas,$canvas, $v[1],$v[2],0,0,$new_width,$new_height, 100);
                }else{

                    $src0 = imagecreatefrompng($v[0]); //二维码
                    $src0X = imagesx($src0);
                    $src0Y = imagesy($src0);

                    imagecopymerge($this->canvas,$src0, $v[1],$v[2],0,0,$src0X,$src0Y, 100);

                }
            }
        }else{
            if($Zoom){
                $src = imagecreatefrompng($src); //二维码
                $srcX = imagesx($src);
                $srcY = imagesy($src);

                $new_width = $Zoom;
                $new_height = $Zoom / $srcX * $srcY;

                // 创建画布
                $canvas = imagecreatetruecolor($new_width,$new_height);

                // 拷贝图片
                imagecopyresampled($canvas,$src,0,0,0,0,$new_width,$new_height,$srcX,$srcY);
                // 剧中
                if(!$x){
                    $x = ($this->srcSx - $new_width) / 2; //文字居中
                }

                imagecopymerge($this->canvas,$canvas, $x,$y,0,0,$new_width,$new_height, 100);
            }else{
                $src = imagecreatefrompng($src); //二维码  多张可循环
                imagecopymerge($this->canvas,$src, $x,$y,0,0,imagesx($src),imagesy($src), 100);
            }
        }

        return $this;
    }

    /**
     *   图片加入文字 public 共有方法
     *   $txt type = str
     *      (1) $txt     str   要加入得文字 默认:空
     *      (2) $color   str   字体颜色 rgb 255,255,255 默认:0,0,0
     *      (3) $x       int   x 轴像素 默认: 0
     *      (4) $y       int   y 轴像素 默认: 0
     *      (5) $ttf     int   字体文件 默认: ./ttf/heiti.ttf
     *      (6) $size    int   字体大小 默认: 10
     *      (7) $angle   int   字体角度 默认: 0
     *      
     *   $txt type = arr
     *       [
     *           0 => str   要加入得文字 默认:空
     *           0 => str   字体颜色 rgb 255,255,255 默认:0,0,0
     *           0 => str   x 轴像素 默认: 0
     *           0 => str   y 轴像素 默认: 0
     *           0 => str   要加入得文字 默认:空
     *           0 => str   要加入得文字 默认:空
     *           0 => str   要加入得文字 默认:空
     *       ]
     *
     *   返回
     *       $this       当前操作对象
     *   使用
     *       $this->save 保存
     *       $this->show 显示在浏览器
     */

    public function picText($txt = false, $color = false, $x = false, $y = false, $ttf = false, $size = false, $angle = false)
    {
        $txt = $txt ? $txt : '';
        $color = $color ? $color : '0,0,0';
        $x = (int)$x ? $x : 0;
        $y = (int)$y ? $y : 16;
        $size = (int)$size ? $size : 16;
        $angle = (int)$angle ? $angle : 0;
        $ttf = file_exists($ttf) ? $ttf : "./web/ttf/heiti.ttf";
        if(!file_exists($ttf)){
            exit("未找到字体文件");
        }

        // 给文字指定一个编码，避免乱码
        mb_internal_encoding("UTF-8"); 

        $colorArr = explode(',',$color);
        $colorArr[0] = isset($colorArr[0]) ? (int)$colorArr[0] : 0 ;
        $colorArr[1] = isset($colorArr[1]) ? (int)$colorArr[1] : 0 ;
        $colorArr[2] = isset($colorArr[2]) ? (int)$colorArr[2] : 0 ;
        if($colorArr[0] == 255 && $colorArr[1] == 255 && $colorArr[2] == 255){
            $col = imagecolorallocate($this->canvas, 0xFF, 0xFF, 0xFF);
        }else{
            $col = imagecolorallocate($this->canvas, $colorArr[0], $colorArr[1], $colorArr[2]);
        }

        $txt_max_width = intval(0.8*$this->srcSx);
        $content = "";
        $letter = [];
        for ($i=0;$i<mb_strlen($txt);$i++) {
            $letter[] = mb_substr($txt, $i, 1);
        }
        if($letter){
            foreach ($letter as $l) {
                $teststr = $content." ".$l;
                $testbox = imagettfbbox($size,$angle,$ttf,$teststr);
                // 判断拼接后的字符串是否超过预设的宽度。超出宽度添加换行
                if (($testbox[2] > $txt_max_width) && ($content !== "")) {
                    $content .= "\n";
                }
                $content .= $l;
            }
        }

        // $y 文字从高度开始

        if(!$x && $letter){
            $txt_width = $testbox[2]-$testbox[0];
            $x = ($this->srcSx - $txt_width) / 2; //文字居中
            $x -= $size;
        }

        imagettftext($this->canvas,$size,$angle,$x,$y,$col,$ttf,$content); //写 TTF 文字到图中
        

        return $this;

	}

     /**
     *   等比例压缩图片 public
     *   
     *      (1)$imgW    要缩放像素大小 默认:300
     *
     *   返回
     *      $src        图片得路径
     */

    public function picZoom($imgW=300){

        // 压缩后的图片长宽
        $new_width = $imgW;
        $new_height = $imgW / $this->srcSx * $this->srcSy;

        // 创建画布
        $canvas = imagecreatetruecolor($new_width,$new_height);

        // 拷贝图片
        imagecopyresampled($canvas,$this->canvas,0,0,0,0,$new_width,$new_height,$this->srcSx,$this->srcSy);

        $this->srcSx = $new_width;
        $this->srcSy = $new_height;

        $this->canvas = $canvas;

        return $this;
    }

    /**
     *   保存图片  public 共有方法
     *      $isSrc  =   1  覆盖源文件保存
     *              =   3  另存文件
     *                  $can1 = 另保存得路径
     *              
     *   返回
     *      str       图片得路径信息
     */

    public function save($isSrc = 1,$src = '')
    {
        if($isSrc){
            imagepng($this->canvas,$this->src);
            $src = $this->src;
        }else{
            imagepng($this->canvas,$src);
        }

        return trim($src,'.');
    }

    public function show()
    {
        $this->pictype = $this->pictype ? $this->pictype : 'png';
        header("Content-type: image/".$this->pictype);
        imagepng($this->canvas);
        // imagedestroy($this->canvas);
    }

    //将图片背景改成透明
    public function transparent($src = '')
    {
        //将人物和装备图片分别取到两个画布中        
        $src = imagecreatefrompng($src); 
        $srcSx   = imagesx($src);
        $srcSy   = imagesy($src);     
        //创建一个和人物图片一样大小的真彩色画布
        //（ps：只有这样才能保证后面copy装备图片的时候不会失真）        
        $image_2 = imageCreatetruecolor($srcSx,$srcSy);        
        //为真彩色画布创建白色背景，再设置为透明        
        $color = imagecolorallocate($image_2, 255, 255, 255);
        $color = imagecolorallocate($image_2, 1000, 1000, 1000);        
        imagefill($image_2, 0, 0, $color);        
        imageColorTransparent($image_2, $color);        
        return [$image_2,$src,$srcSx,$srcSy];
    }

    /**
     * 图片压缩
     * @param $src 源图
     * @param float $percent  压缩比例
     */
    public static function yZoom($src, $percent=1,$resrc = '')
    {
        
        $imgGd = new imgGd();
        $imgGd->src = $src;
        $imgGd->percent = $percent;
        if(!$resrc){
            $resrc = $src;
        }

        $imgGd->_openImage();
        $imgGd->_saveImage($resrc);  //保存

        return $resrc;
    }

    public static function dbzoom($src, $percent=1,$resrc = '')
    {
        
        $imgGd = new imgGd();
        $imgGd->src = $src;
        $imgGd->percent = $percent;
        if(!$resrc){
            $resrc = $src;
        }

        $imgGd->_openImage();
        $imgGd->_saveImage($resrc);  //保存

        return $imgGd->imageinfo;
    }

    public function yszoom($src, $percent=1)
    {
        $this->src = $src;
        $this->percent = $percent;
    }
    /** 高清压缩图片
     * @param string $saveName  提供图片名（可不带扩展名，用源图扩展名）用于保存。或不提供文件名直接显示
     */
    public function compressImg($saveName='')
    {
        $this->_openImage();
        if(!empty($saveName)) $this->_saveImage($saveName);  //保存
        else $this->_showImage();

        return $this->imageinfo;
    }
    /**
     * 内部：打开图片
     */
    private function _openImage()
    {
        list($width, $height, $type, $attr) = getimagesize($this->src);
        $this->imageinfo = array(
            'width'=>$width,
            'height'=>$height,
            'type'=>image_type_to_extension($type,false),
            'attr'=>$attr
        );
        $fun = "imagecreatefrom".$this->imageinfo['type'];
        $this->image = $fun($this->src);
        $this->_thumpImage();
    }
    /**
     * 内部：操作图片
     */
    private function _thumpImage()
    {
        $new_width = $this->imageinfo['width'] * $this->percent;
        $new_height = $this->imageinfo['height'] * $this->percent;
        $image_thump = imagecreatetruecolor($new_width,$new_height);
        //将原图复制带图片载体上面，并且按照一定比例压缩,极大的保持了清晰度
        imagecopyresampled($image_thump,$this->image,0,0,0,0,$new_width,$new_height,$this->imageinfo['width'],$this->imageinfo['height']);
        imagedestroy($this->image);
        $this->image = $image_thump;
    }
    /**
     * 输出图片:保存图片则用saveImage()
     */
    private function _showImage()
    {
        header('Content-Type: image/'.$this->imageinfo['type']);
        $funcs = "image".$this->imageinfo['type'];
        $funcs($this->image);
        imagedestroy($this->image);
    }
    /**
     * 保存图片到硬盘：
     * @param  string $dstImgName  1、可指定字符串不带后缀的名称，使用源图扩展名 。2、直接指定目标图片名带扩展名。
     */
    private function _saveImage($dstImgName)
    {
        if(empty($dstImgName)) return false;
        $allowImgs = ['.jpg', '.jpeg', '.png', '.bmp', '.wbmp','.gif'];   //如果目标图片名有后缀就用目标图片扩展名 后缀，如果没有，则用源图的扩展名
        $dstExt =  strrchr($dstImgName ,".");
        $sourseExt = strrchr($this->src ,".");
        if(!empty($dstExt)) $dstExt =strtolower($dstExt);
        if(!empty($sourseExt)) $sourseExt =strtolower($sourseExt);
        //有指定目标名扩展名
        if(!empty($dstExt) && in_array($dstExt,$allowImgs)){
            $dstName = $dstImgName;
        }elseif(!empty($sourseExt) && in_array($sourseExt,$allowImgs)){
            $dstName = $dstImgName.$sourseExt;
        }else{
            $dstName = $dstImgName.$this->imageinfo['type'];
        }
        $funcs = "image".$this->imageinfo['type'];
        $funcs($this->image,$dstName);

        imagedestroy($this->image);
    }


    public static function logText()
    {
        echo '<pre>
            public static function imgZoom($src = "", $imgW=468, $prefix = "")
                /**
                 *   等比例压缩图片 public static 静态方法
                 *   
                 *      (1)$src        要缩放得图片路径   默认:空 
                 *      (2)$out_with   缩放至宽度         默认:468
                 *      (3)$prefix     另存图片得补充     默认:空
                 *
                 *   返回
                 *      $src        图片得路径
                 */
            
            public static function img($src = "")
                /**
                 *   等比例压缩图片 public static 静态方法
                 *   
                 *      (1)$src        背景图片路径   默认:空 
                 *
                 *   返回
                 *      对象
                 */

            public function imgPic(src = "",x = 0,y = 0)
                /**
                 *   合并图片 public 共有方法
                 *   $src type str
                 *      $src  需要合并得图片
                 *      $x    位置像素 x 轴
                 *      $y    位置像素 y 轴
                 *      $Zoom 缩放得像素
                 *
                 *   $src type arr
                 *       [
                 *           [
                 *               0 => 需要合并得图片,
                 *               1 => 位置像素 x 轴,
                 *               2 => 位置像素 y 轴,
                 *               3 => 缩放得像素,
                 *           ]
                 *       ]
                 * 
                 *
                 *   返回
                 *      $this       处理对象
                 *   使用
                 *      save        保存图片
                 */

            public function picText(txt = false, color = false, x = false, y = false, ttf = false, size = false, angle = false)
                /**
                 *   图片加入文字 public 共有方法
                 *   $txt type = str
                 *      (1) $txt     str   要加入得文字 默认:空
                 *      (2) $color   str   字体颜色 rgb 255,255,255 默认:0,0,0
                 *      (3) $x       int   x 轴像素 默认: 0
                 *      (4) $y       int   y 轴像素 默认: 0
                 *      (5) $ttf     int   字体文件 默认: ./ttf/heiti.ttf
                 *      (6) $size    int   字体大小 默认: 10
                 *      (7) $angle   int   字体角度 默认: 0
                 *      
                 *   $txt type = arr
                 *       [
                 *           0 => str   要加入得文字 默认:空
                 *           0 => str   字体颜色 rgb 255,255,255 默认:0,0,0
                 *           0 => str   x 轴像素 默认: 0
                 *           0 => str   y 轴像素 默认: 0
                 *           0 => str   要加入得文字 默认:空
                 *           0 => str   要加入得文字 默认:空
                 *           0 => str   要加入得文字 默认:空
                 *       ]
                 *
                 *   返回
                 *       $this       当前操作对象
                 *   使用
                 *       $this->save 保存
                 *       $this->show 显示在浏览器
                 */

            public function picZoom($imgW=300)

                /**
                 *   缩放当前图片资源 public
                 *   
                 *      (1)$imgW    要缩放像素大小 默认:300
                 *
                 *   返回
                 *      $src        图片得路径
                 */
            
            public function save($isSrc = 1,$src = "")

                /**
                 *   保存图片  public 共有方法
                 *      $isSrc  =   1  覆盖源文件保存
                 *              =   3  另存文件
                 *                  $can1 = 另保存得路径
                 *              
                 *   返回
                 *      str       图片得路径信息
                 */
                
            public function show()

                /**
                 *      显示当前图片资源
                 */

        ';

    }

}
